import React, { ReactElement, useEffect, useState } from 'react';
import { Image, Text, View, ViewStyle } from 'react-native';

import styles from './style';
import MsgBox, { DirectType } from '../../../Graph/MsgBox';
import {
  playVoice1,
  playVoice2,
  playVoice3,
  playVoiceR1,
  playVoiceR2,
  playVoiceR3
} from '../../../../../../constant/resource';
import { Message } from '../../../../../../api/class/getMessageList';
import { phonePx } from '../../../../../../util/adapt';
import { CLASS_ROOM_RIGHT_SCALE } from '../../../../constant';
import Button from '../../../../../../components/Button';
import { MAX_MESSAGE_WIDTH, MIN_MESSAGE_WIDTH } from '../../constant';

export enum PlayVoiceType {
  Unknown,
  Bubble,
  Own,
  Other
}

export enum VoiceType {
  Unknown,
  First,
  Second,
  Third
}

interface PlayVoiceProps {
  play: () => void;
  stop?: () => void;
  playVoiceType: PlayVoiceType;
  message: Message;
  style?: ViewStyle | ViewStyle[];
}

export default ({
  style,
  playVoiceType,
  message,
  play,
  stop
}: PlayVoiceProps): ReactElement => {
  const [voiceType, setVoiceType] = useState(VoiceType.Unknown);

  const { isPlay } = message;

  useEffect((): (() => void) => {
    let timer: NodeJS.Timer | null = null;
    const clearTimer = (): void => {
      if (timer) {
        clearInterval(timer);
        timer = null;
      }
    };
    if (isPlay) {
      timer = setInterval((): void => {
        setVoiceType(
          (type): VoiceType => {
            if (!timer) {
              return VoiceType.Unknown;
            }
            if (type === VoiceType.Third || type === VoiceType.Unknown) {
              return VoiceType.First;
            }
            if (type === VoiceType.Second) {
              return VoiceType.Third;
            }
            if (type === VoiceType.First) {
              return VoiceType.Second;
            }
            return VoiceType.Unknown;
          }
        );
      }, 200);
    } else {
      clearTimer();
      setVoiceType(VoiceType.Unknown);
    }

    return (): void => {
      clearTimer();
    };
  }, [isPlay]);

  const { audioMessage } = message;
  const { duration } = audioMessage;

  let fillColor = 'rgba(243, 243, 243, 1)';
  if (playVoiceType === PlayVoiceType.Own) {
    fillColor = 'rgba(247, 215, 106, 1)';
  } else if (playVoiceType === PlayVoiceType.Other) {
    fillColor = 'rgba(246, 246, 246, 1)';
  }

  let directType = DirectType.Bottom;
  if (playVoiceType === PlayVoiceType.Own) {
    directType = DirectType.Right;
  } else if (playVoiceType === PlayVoiceType.Other) {
    directType = DirectType.Left;
  }

  let messageWidth = MAX_MESSAGE_WIDTH;
  if (playVoiceType !== PlayVoiceType.Bubble) {
    messageWidth = duration * phonePx(10) * CLASS_ROOM_RIGHT_SCALE;
    if (messageWidth >= MAX_MESSAGE_WIDTH) {
      messageWidth = MAX_MESSAGE_WIDTH;
    } else if (messageWidth < MIN_MESSAGE_WIDTH) {
      messageWidth = MIN_MESSAGE_WIDTH;
    }
  }
  return (
    <MsgBox
      style={style}
      fillColor={fillColor}
      directType={directType}
      dia={phonePx(4) * CLASS_ROOM_RIGHT_SCALE}
      surfaceWidth={messageWidth}
    >
      {directType !== DirectType.Right ? (
        <Button
          style={styles.content}
          onPress={(): void => {
            if (isPlay) {
              if (stop) {
                stop();
              }
            } else {
              play();
            }
          }}
        >
          <View style={styles.playContent}>
            <Image
              source={playVoice3}
              style={[
                styles.voice,
                voiceType === VoiceType.Unknown || voiceType === VoiceType.Third
                  ? {}
                  : styles.hidden
              ]}
              resizeMode="contain"
            />
            <Image
              source={playVoice2}
              style={[
                styles.voice,
                voiceType === VoiceType.Second ? {} : styles.hidden
              ]}
              resizeMode="contain"
            />
            <Image
              source={playVoice1}
              style={[
                styles.voice,
                voiceType === VoiceType.First ? {} : styles.hidden
              ]}
              resizeMode="contain"
            />
          </View>
          <View style={styles.timeContent}>
            <Text style={styles.time}>{duration}</Text>
            {/* eslint-disable-next-line react/no-unescaped-entities */}
            <Text style={styles.time}>''</Text>
          </View>
        </Button>
      ) : (
        <Button
          style={[styles.content, styles.rightContent]}
          onPress={(): void => {
            if (isPlay) {
              if (stop) {
                stop();
              }
            } else {
              play();
            }
          }}
        >
          <View style={styles.timeContent}>
            <Text style={styles.time}>{duration}</Text>
            {/* eslint-disable-next-line react/no-unescaped-entities */}
            <Text style={styles.time}>''</Text>
          </View>
          <View style={styles.rightPlayContent}>
            <Image
              source={playVoiceR3}
              style={[
                styles.voice,
                voiceType === VoiceType.Unknown || voiceType === VoiceType.Third
                  ? {}
                  : styles.hidden
              ]}
              resizeMode="contain"
            />
            <Image
              source={playVoiceR2}
              style={[
                styles.voice,
                voiceType === VoiceType.Second ? {} : styles.hidden
              ]}
              resizeMode="contain"
            />
            <Image
              source={playVoiceR1}
              style={[
                styles.voice,
                voiceType === VoiceType.First ? {} : styles.hidden
              ]}
              resizeMode="contain"
            />
          </View>
        </Button>
      )}
    </MsgBox>
  );
};
